package com.chery.media.music

import android.Manifest
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothManager
import android.bluetooth.BluetoothProfile
import android.content.ComponentName
import android.content.Context
import android.content.IntentFilter
import android.content.pm.PackageManager
import android.support.v4.media.MediaBrowserCompat
import android.support.v4.media.MediaMetadataCompat
import android.support.v4.media.session.MediaControllerCompat
import android.support.v4.media.session.PlaybackStateCompat
import androidx.core.app.ActivityCompat
import androidx.lifecycle.MutableLiveData
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.Utils
import com.chery.media.network.model.MusicPlayBean
import com.chery.media.ui.music.musicViewModel
import com.chery.media.ui.play.playViewModel

object BluetoothMusicTool: IBluetoothMusicTool {

    //蓝牙音乐service
    private const val MEDIA_BROWSER_SERVICE_PACKAGE = "com.android.bluetooth"
    private const val MEDIA_BROWSER_SERVICE =
        "com.android.bluetooth.a2dpsink.mbs.A2dpMediaBrowserService"
//        "com.android.bluetooth.avrcpcontroller.BluetoothMediaBrowserService"
    private var mediaBrowser: MediaBrowserCompat? = null
    private var mediaControllerCompat: MediaControllerCompat? = null
    private const val BLUETOOTH_REQUEST_CODE = 100
    private var isPlaying = false

    private val app = Utils.getApp()

    var mediaMetadataCompat = MutableLiveData<MediaMetadataCompat>()

    var playbackStateCompat = MutableLiveData<PlaybackStateCompat>()
    private var isPlayAudioFocus = false
    private const val UNKNOWN = "未知"

    // 当前专辑信息
    private var currentAlbum = ""

    //在Application中初始化蓝牙连接操作
    override fun init() {
        val componentName = ComponentName(MEDIA_BROWSER_SERVICE_PACKAGE, MEDIA_BROWSER_SERVICE)
        mediaBrowser = MediaBrowserCompat(
            app,
            componentName,
            connectionCallbacks,
            null
        )
        mediaBrowser?.connect()
        //注册蓝牙状态监听广播
        registerBluetoothBroadcast()
    }
    private fun registerBluetoothBroadcast() {
        val broadcastReceiver = BluetoothBroadcastReceiver()
        val intentFilter = IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED)
        intentFilter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)
        app.registerReceiver(broadcastReceiver, intentFilter)
    }


    private val connectionCallbacks: MediaBrowserCompat.ConnectionCallback =
        object : MediaBrowserCompat.ConnectionCallback() {
            override fun onConnected() {
                // Android 7-9的service     com.android.bluetooth.a2dpsink.mbs.A2dpMediaBrowserService
                //蓝牙音乐服务连接成功
                LogUtils.eTag("BluetoothMusicTool", "bluetooth music connect success")
                if (mediaBrowser?.isConnected == true) {
                    mediaBrowser?.sessionToken.also { token ->
                        mediaControllerCompat = MediaControllerCompat(app, token!!)
                        //注册蓝牙音乐信息状态监听
                        if (mediaControllerCompat?.metadata != null) {
                            mediaMetadataCompat.value = mediaControllerCompat?.metadata
                            sendCurrentMusicInfo()
                        }
                        mediaControllerCompat?.registerCallback(controllerCallback)
                    }
                }
            }

            override fun onConnectionSuspended() {
                LogUtils.eTag("BluetoothMusicTool", "bluetooth music connect suspend")
            }

            override fun onConnectionFailed() {
                LogUtils.eTag("BluetoothMusicTool", "bluetooth music connect failed")
            }
        }

    private val controllerCallback: MediaControllerCompat.Callback =
        object : MediaControllerCompat.Callback() {
            override fun onMetadataChanged(metadata: MediaMetadataCompat?) {
                mediaMetadataCompat.value = metadata
                sendCurrentMusicInfo()
            }

            override fun onPlaybackStateChanged(state: PlaybackStateCompat?) {
                state?.let { playInfo ->
                    playbackStateCompat.value = playInfo
                    sendCurrentMusicInfo()
                }
            }
        }
    fun unregisterCallback() {
//        if (isBluetoothHeadsetConnected(Utils.getApp()) && mediaBrowser.isConnected) {
//            mediaControllerCompat.unregisterCallback(controllerCallback)
//        }
        if (mediaControllerCompat != null)
            mediaControllerCompat?.unregisterCallback(controllerCallback)
    }

    private fun sendCurrentMusicInfo() {
//        val currentMusic = MusicPlayBean(
//            0,
//            mediaControllerCompat?.metadata?.getString(MediaMetadataCompat.METADATA_KEY_ARTIST),
//            mediaControllerCompat?.metadata?.getString(MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI)?: "",
//            mediaControllerCompat?.metadata?.getString(MediaMetadataCompat.METADATA_KEY_TITLE)?: "",
//            mediaControllerCompat?.metadata?.getString(MediaMetadataCompat.METADATA_KEY_TITLE)?: "",
//            "${mediaControllerCompat?.playbackState?.position?:0}",
//            "${mediaControllerCompat?.metadata?.getLong(MediaMetadataCompat.METADATA_KEY_DURATION)?:0}",
//            mediaControllerCompat?.playbackState?.state == PlaybackStateCompat.STATE_PLAYING
//        )
//        musicViewModel.currentPlayMusic.postValue(currentMusic)
        LogUtils.eTag(this.javaClass.name, mediaControllerCompat?.metadata?.getString(MediaMetadataCompat.METADATA_KEY_TITLE)?: "")
        playViewModel.currentBluetoothPlayMusic.value = MusicPlayBean(
            0,
            mediaControllerCompat?.metadata?.getString(MediaMetadataCompat.METADATA_KEY_ARTIST),
            mediaControllerCompat?.metadata?.getString(MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI)?: "",
            mediaControllerCompat?.metadata?.getString(MediaMetadataCompat.METADATA_KEY_TITLE)?: "",
            mediaControllerCompat?.metadata?.getString(MediaMetadataCompat.METADATA_KEY_TITLE)?: "",
            "${mediaControllerCompat?.playbackState?.position?:0}",
            "${mediaControllerCompat?.metadata?.getLong(MediaMetadataCompat.METADATA_KEY_DURATION)?:0}",
            mediaControllerCompat?.playbackState?.state == PlaybackStateCompat.STATE_PLAYING
        )
    }

    /**
     * 检测蓝牙是否连接
     */
    fun isBluetoothHeadsetConnected(context: Context): Boolean {
        val bluetoothManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as? BluetoothManager
        val bluetoothAdapter = bluetoothManager?.adapter
        return if (bluetoothAdapter != null) {
            val connectedDevices = if (ActivityCompat.checkSelfPermission(
                    context,
                    Manifest.permission.BLUETOOTH_CONNECT
                ) != PackageManager.PERMISSION_GRANTED
            ) {
                return false
            } else
                bluetoothAdapter.getProfileConnectionState(BluetoothProfile.HEADSET)
            connectedDevices == BluetoothProfile.STATE_CONNECTED
        } else {
            false
        }
    }

    fun seekTo(position: Long) {
        if (mediaControllerCompat == null || mediaControllerCompat?.transportControls == null) {
            return
        }
        val mediaControllerCntrl = mediaControllerCompat?.transportControls
        mediaControllerCntrl?.seekTo(position)
    }

    fun operateMusic(type: OperateMusicType): Boolean {
        if (mediaControllerCompat == null || mediaControllerCompat?.transportControls == null) {
            return false
        }
        val mediaControllerCntrl = mediaControllerCompat?.transportControls
        when(type) {
            OperateMusicType.PLAY -> {
                mediaControllerCntrl?.play()
            }
            OperateMusicType.PAUSE -> {
                mediaControllerCntrl?.pause()
            }
            OperateMusicType.NEXT -> {
                mediaControllerCntrl?.skipToNext()
            }
            OperateMusicType.PREVIOUS -> {
                mediaControllerCntrl?.skipToPrevious()
            }
            OperateMusicType.STOP -> {
                mediaControllerCntrl?.stop()
            }
        }
        return true
    }

}
